/**
 * 页面 JS Tree 的实现
 * @version 2.2
 */

getUniqueID = function(){
	return ('_' + (new Date().getTime()) + '_' + parseInt(Math.random()*10000));
}

/**
 * @class TreePanel
 */
TreePanel = function(config){
	this.nodeHash = {};
	this.root = null;
	this._id = getUniqueID();
	this.iconPath = 'img/';
	this.eventListeners = {'click':{},'dblclick':{},'contextmenu':{},'mousedown':{}};
	this.element = document.createElement('div');
	this.element.className='TreePanel';
	this.container = null;
	this.focusNode = null;
	this.on=this.addListener;
	this.attribute = {};
	this.initialize.apply(this, arguments);
};

TreePanel.prototype={
	initialize : function(config){
		this.attribute.asyncUrl = config['asyncUrl'];
		this.attribute.textWidth = config['textWidth'] || '100px';
		var renderTo = config['renderTo'];
		this.container = (String.isInstance(renderTo) ? document.getElementById(renderTo) : renderTo ) || document.body;
		var handler= config['handler'];
		if(Function.isInstance(handler)){
			this.addListener('click',handler);
		}
		var iconPath = config['iconPath'];
		if(String.isInstance(iconPath)){
			this.iconPath = iconPath;
		}
		
		var node = new TreeNode(config.root);
		this.setRootNode(node);
	},
	pathSeparator: "/",
	/**
	 * @description 得到此树的根结点
	 * @return 根结点(TreeNode)
	 */
	 getRootNode : function(){
			return this.root;
	},
	setRootNode : function(node){
		this.root = node;
		node.ownerTree = this;
		this.registerNode(node);
		node.cascade((function(node){
			this.registerNode(node);
		}),this);
	},
	/**
	 * 根据结点的ID查找到结点，如果没有查找到，则返回null
	 * @param id 结点ID
	 * @return node 返回查找到子结点
	 */
	getNodeById : function(id){
		return this.nodeHash[id];
	},
	registerNode : function(node){
		this.nodeHash[node.id] = node;
	},
	unregisterNode : function(node){
		delete this.nodeHash[node.id];
	},
	/**
	 * @description 渲染在renderTo标识的DIV中，如果没有renderTo，则默认为body。 <P>在TreePanel.config设置renderTo
	 */
	render : function(){
		this.element.innerHTML = '';
		this.root.render();
		if(this.container){
			this.container.appendChild(this.element);
		}
		this.initEvent(); 
	},
	setIconPath : function(iconPath){
		this.iconPath=iconPath;
	},
	getIcon : function(icontype){
		return  this.icon[icontype]
	},
	getIconByType : function(type){
		return type;
	},
	isAsyncTree : function()
	{
		return this.attribute.asyncUrl != undefined && this.attribute.asyncUrl != '';
	},
	initEvent : function(){
		//在事件处理函数中调用this返回的是HTML元素，因此要保留对树对象的引用
		var _this = this;
		
		//处理鼠标单击事件的函数，如果是加减号，则收缩/展开节点，如果是图标或者文本，则选择节点，如果是多选框，则选中节点
		var nodeClickEventHandler=function(elemType,node)
		{
			if(elemType == 'clip')
			{
				if(node.isExpand)
					node.collapse();
				else
					node.expand();
			}
			else if(elemType == 'icon' || elemType == 'text')
			{
				_this.setFocusNode(node);
			}
			else if(elemType == 'checked')
			{
				node.onCheck();
			}
		};
		
		//通用的事件处理函数，如果是单击事件，则调用单击事件处理函数，如果是文本节点，则依次调用相应事件列表里的函数
		var nodeEventListener = function(event)
		{
			var event = event || window.event;
			var elem=(event.srcElement || event.target);
			var _type = elem['_type_'];
			if(typeof(_type) === undefined)	return true;
			elem = elem.parentNode || elem.parentElement;
			var node = null;
			if(elem.indexId!=null) node = _this.nodeHash[ elem.indexId ];
			if(node == null) return true;
			if(event.type === 'click')
			{
				nodeClickEventHandler(_type,node);
			}
			if(_type === 'text')
			{
				if(_this.eventListeners[event.type] == undefined) return ;
				try
				{
					return _this.eventListeners[event.type](node,event);
				}
				catch(err)
				{
				}
			}
		};
		
		var nodeMouseDownEventListener = function(node)
		{
			_this.setFocusNode(node);
		}
		//注册eventListeners中所有的事件类型
		for(var eventType in _this.eventListeners){
			eval('this.element.on'+eventType+'=nodeEventListener;');
		}
		this.addListener('mousedown',nodeMouseDownEventListener);
	},
	asyncLoadNodes : function(node)
	{
		var params = 'nodeId='+node.id
		var httpRequest = new HttpRequest();
		httpRequest.SendRequest(this.attribute.asyncUrl,params,false,null);
		var s = httpRequest.GetResponseText();
		var children = eval('('+s+')');
		for(var i=0,j=children.length;i<j;i++){
			node.appendChild(new TreeNode(children[i]));
		}
	},
	setCheckedNode : function(node,check){ 
	   if(String.isInstance(node) ){
		   	//如果是String类型，则认为node是nodeid
		   	node=this.getNodeById(node);
		  }
		 	if(check===0){
		 			node.cascade(node.setCheck , null,0);
					node.bubble(node.setCheck , null,2);
			}else{ 
		 			node.cascade(node.setCheck , null,1);
					node.bubble(node.setCheck , null,3);
			}
	},
	
	/**
	 * 设置选中的结点
	* @param  nodes  一个TreeNode的数组或者String类型的NodeId数组
	* @param checked 1是选中，0是取消选择
	**/
	setCheckedNodes : function(nodes,check){
		if(Array.isInstance(nodes) ){ 
		    for(var i=0;i<nodes.length;i++){ 
		       this.setCheckedNode (nodes[i],check);
		    }
		}
		else
		{
			this.setCheckedNode (node,check);
		}
	},
	/**
	 * 此函数是将指定的结点select，即将背景变黑的那种选中，不是多选框的选中，多选框的选中请参考setCheckedNodes
	 * @param node 一个字符串的nodeId或者一个TreeNode类型的node
	 * @param node check=0表示取消选中，check=1选中
	 */
	//将结点选中,check=0是不选中，check=1选中,node可以是TreeNode类型，也可以是String类型的nodeId
	select : function(node,check){
	    if(String.isInstance(node) )
	    {
		   	//如果是String类型，则认为node是nodeid
		   	node=this.getNodeById(node);
		}
		
		if(check==0)
		{
			node.unselect();
			if(this.focusNode == node)
			{
				this.focusNode = null;
			}
		}
		else if(check==1)
		{
			if(this.focusNode != null && this.focusNode != node)
			{
				this.focusNode.unselect();				
			}
			this.focusNode = node;
			node.select();
			if(node.parentNode)
			{
				node.parentNode.expand();
			}
		}	
	},
	/**
	 * 此函数用于返回选中的node数组，此函数的两个参数暂时没有用到<p>注：只是返回叶子结点，非叶子点即使选中，也不会返回
	 */
	getCheckedNodes : function(nodeLevel,check)
	{
		var checkeds = [];
		for(var k in this.nodeHash)
		{
			var node = this.nodeHash[k];
			if(node.checked==1 && node.isLeaf())
			{
					checkeds.push(node);
			}
		}
		return checkeds;
	}
	,
	/**
	 * 此函数用于返回选中的node的属性数据数组，此函数的后面两个参数暂时没有用到<p>
	 * 注：只是返回叶子结点，非叶子点即使选中，也不会返回
	 * @param attr  一个String类型的属性名
	 */
	getCheckedNodesAttrabute : function(attr,nodeLevel,check){
		var checkeds = [];
		attr = attr||'id';
		for(var k in this.nodeHash){
			var node = this.nodeHash[k];
			if(node.checked==1 && node.isLeaf()){
				var value = node.attributes[attr]
				if(value != null){
					checkeds.push(value);
				}
			}
		}
		return checkeds;
	},
	/**
	 * 树加触发事件
	 * @param eventType 事件类型，有'click','contextmenu','dblclick'等
	 * @param eventHandler 事件处理函数
	 */
	addListener : function(eventType,eventHandler){
		if(Function.isInstance(eventType)){
			handler=eventType;
			eventType === 'click';
		}
		if(this.eventListeners[eventType] == undefined)
		{
			return false;
		}
		this.eventListeners[eventType] = eventHandler;
		return true;
	},
	/**
	 * 设置树的焦点节点，将指定的结背景变，参select
	 * @param node 一个字符串的nodeId或者一个TreeNode类型的node
	 */
	setFocusNode : function(node){
		if(this.focusNode){
			this.focusNode.unselect();
		}
		this.focusNode = node;
		if(node.parentNode){
			node.parentNode.expand();
		}
		node.select();
	},
	toString : function(){
		return "[Tree"+(this.id?" "+this.id:"")+"]";
	},
	/**
	 * 将树全部折叠
	 */
	collapseAll : function(){
		if(this.root){
			this.root.collapseChildNodes(true);
		}
	},
	/**
	 * 将树全部展开
	 */
	expandAll : function(){
		if(this.root){
			this.root.expand(true);
		}
	}
};


TreePanel.prototype.icon = {
	root		: 'root',
	folder		: 'folder',
	folderOpen	: 'folderOpen',
	node		: 'page',
	empty	    : 'empty',
	line	 	: 'line',
	join	 	: 'join',
	joinBottom	: 'joinBottom',
	plus	 	: 'plus',
	plusBottom	: 'plusBottom',
	minus	 	: 'minus',
	minusBottom	: 'minusBottom',
	nlPlus	 	: 'nlPlus',
	nlMinus	 	: 'nlMinus',
	checkbox0 	:	'checkbox_0',
	checkbox1 	:	'checkbox_1',
	checkbox2	:	'checkbox_2',
	org		 	: 'org.gif',
	edp	  		: 'edp.gif',
	emp	 		: 'emp.gif'
	
};

/**
 * @class TreeNode
 */
TreeNode=function(attributes) {
	this['attributes'] = attributes || {};
	this['html-element'] = false;//null
	if(!attributes.id){
		attributes.id = getUniqueID();
	}
	this.id = attributes.id;
	this.parentNode = null;
  this.childNodes = [];
	this.parentNode = null;
	this.lastChild = null;
	this.firstChild = null;
	this.previousSibling = null;
	this.nextSibling = null;
	this.childrenRendered = false
	this.isExpand = false;

	this.checked = this['attributes']['checked'];
	this.checked = this.checked==null ? false : this.checked;

	this.leaf = this.attributes.leaf;
	var children = attributes.children || [];
	for(var i=0,j=children.length;i<j;i++){
		var node = new TreeNode(children[i]);
		this.appendChild(node);
	}
}
/**
 * @class TreeNode
 */
 
TreeNode.prototype={
	initEl : function(){
		this['html-element']={};
		this['html-element']['element'] = document.createElement('div');
		this['html-element']['line']	 = document.createElement('span');
		this['html-element']['clip']	 = document.createElement('span');
		this['html-element']['icon']	 = document.createElement('span');
		this['html-element']['text']	 = document.createElement('span');
 		this['html-element']['checkbox'] = document.createElement('span');
		this['html-element']['child'] = document.createElement('div');
		this['html-element']['element'].appendChild(this['html-element']['line']);
		this['html-element']['element'].appendChild(this['html-element']['clip']);
		this['html-element']['element'].appendChild(this['html-element']['icon']);
		this['html-element']['element'].appendChild(this['html-element']['checkbox']);	
		this['html-element']['element'].appendChild(this['html-element']['text']);
		this['html-element']['element'].appendChild(this['html-element']['child']);
		this['html-element']['text'].className='TreeNode'
		this['html-element']['text'].style.width=this.getOwnerTree().attribute.textWidth;
		this['html-element']['element'].noWrap='true';
		this['html-element']['line']['_type_'] ='line';
		this['html-element']['clip']['_type_'] ='clip';
		this['html-element']['icon']['_type_'] ='icon';
		this['html-element']['text']['_type_'] ='text';
		this['html-element']['checkbox']['_type_'] ='checked';
		this['html-element']['child'].style.display='none';
		if(this.checked===false){
			this['html-element']['checkbox'].style.display='none';
		}
	},
	render : function(){
		if(!this['html-element']){
			this.initEl();
		}
		if(this.isRoot()){
			this.ownerTree.element.appendChild(this['html-element']['element']);
			this.expand();
		}else{
			this.parentNode['html-element']['child'].appendChild(this['html-element']['element']);
		}
		this.paintPrefix();
		this['html-element']['element'].indexId = this.id;
	},
	paintPrefix : function(){
		this.paintLine();
		this.paintClipIcoImg();
		this.paintCheckboxImg();
		this.paintIconImg();
		this.paintText();
	},
	 
	paintLine : function(){
		var ownerTree = this.getOwnerTree();
		this['html-element']['line'].innerHTML = '';
		var pathNodes = this.getPathNodes();
		for(var i = 1 ,count = pathNodes.length-1 ; i < count ; i++){
				var node = pathNodes[i];
				var img = document.createElement('span');
				if( node.isLast()){
					img.className = ownerTree.getIcon('empty');
				}else{
					img.className = ownerTree.getIcon('line');
				}
				this['html-element']['line'].appendChild(img);
		}
	},
	paintClipIcoImg : function(){
		if(this.isRoot()){
			this['html-element']['clip'].style.display='none';//不显示根节点的clip
			return;
		}
		var ownerTree = this.getOwnerTree();
		var icon = 'empty';
		if(this.isRoot()){
			icon = this.isExpand ? 'nlMinus':'nlPlus';
		}else{
			if(this.isLeaf()){ //是叶节点
				if(this.isLast()){
					icon = 'joinBottom';
				}else{
					icon = 'join';
				}
			}else{ //非叶节点
				if(this.isExpand){ //展开
					if(this.isLast()){
						icon = 'minusBottom';
					}else{
						icon = 'minus';
					}
				}else{ //折叠
					if(this.isLast()){
						icon = 'plusBottom';
					}else{
						icon = 'plus';
					}
				}
			}
		};
		this['html-element']['clip'].className = ownerTree.getIcon(icon);
	},
	paintIconImg : function(){
		var ownerTree = this.getOwnerTree();
		var icon = this['attributes']['icon'];
		if(!icon){
			var type = this['attributes']['type']
			
			if(type){
				icon = ownerTree.getIconByType(type);
			}
			if(!icon){
				if(this.isRoot()){
					icon = 'root';
				}else if(this.isLeaf()){
					icon = 'node';
				}else if(this.isExpand){
					icon = 'folderOpen';
				}else{
					icon = 'folder';
				}
			}
		}
		if(icon=='node'&&this['attributes']['img']){
			if(this['attributes']['img']=='risk_blue'){
				this['html-element']['icon'].className = 'risk_blue';
			}else if(this['attributes']['img']=='risk_yellow'){
				this['html-element']['icon'].className = 'risk_yellow';
			}else if(this['attributes']['img']=='risk_red'){
				this['html-element']['icon'].className = 'risk_red';
			}
		}else{
			this['html-element']['icon'].className = ownerTree.getIcon(icon);
		}
		
	},
	paintCheckboxImg : function(){
		var ownerTree = this.getOwnerTree();
		var checked = this.checked;
		if(this['html-element']){
			this['html-element']['checkbox'].className = ownerTree.getIcon(((checked==2)?'checkbox2':(checked==1)?'checkbox1':'checkbox0'));
		}
	},	
	paintText : function(){
		var text = 	this['attributes']['text'];
		this['html-element']['text'].style.cursor='hand'
		//this['html-element']['text'].title=text;
		this['html-element']['text'].innerHTML=text;
		//this['html-element']['text'].textContent=text;
	},
	paintChildren : function(){
		if(!this.childrenRendered){
			this['html-element']['child'].innerHTML = '';
			this.childrenRendered = true;
			var childNodes = this.childNodes;
			for(var i=0;i < childNodes.length;i++){
				childNodes[i].render();
			}
		};
	},
	/**
	 * 收缩下级结点
	 * @param deep true/false，是否递归收缩下级结点，true表示将所有的子结点全部收缩，false表示只收缩第一子级结点
	 */
	collapse : function(deep){
		if(this.isExpand==false) return ;
		this.isExpand=false;
		this['html-element']['child'].style.display='none';
		this.paintIconImg();
		this.paintClipIcoImg();
		if(deep){
			this.collapseChildNodes(deep);
		}
	},
	collapseChildNodes : function(deep){
		var cs = this.childNodes;
		for(var i = 0, len = cs.length; i < len; i++) {
			cs[i].collapse(deep);
		}
	},
	/**
	 * 展开下级结点
	 * @param deep true/false，是否递归展开下级结点，true表示将所有的子结点全部展开，false表示只展开第一子级结点
	 */
	expand : function(deep){
		//如果是第一次加载并且没有子节点，异步加载节点
		var tree = this.getOwnerTree();
		if(!(this.firstExpand == false) && tree.isAsyncTree() && this.childNodes.length==0)
		{
			tree.asyncLoadNodes.call(tree,this);
		}
		this.firstExpand = false;
		if(!this.isLeaf()&&this.childNodes.length>0){
			this.isExpand=true;
			this.paintChildren();
			this['html-element']['child'].style.display='block';
		}
		this.paintIconImg();
		this.paintClipIcoImg();
		if(deep){
			this.expandChildNodes(deep);
		}
	},
	expandChildNodes : function(deep){
		var cs = this.childNodes;
		for(var i = 0, len = cs.length; i < len; i++) {
			cs[i].expand(deep);
		}
	},
	select : function(){
		this.isSelect = true;
		this['html-element']['text'].style.backgroundColor='#CCCCFF';
	},
	unselect : function(){
		this.isSelect = false;
		this['html-element']['text'].style.backgroundColor='';
	},
	getEl :  function(){
		return this['html-element'];
	},
	setCheck : function(checked){
		if(checked==2||checked==3){
			var childNodes = this.childNodes;
			var count = childNodes.length;
			if(count==0){
				this.checked=checked==2?0:1;
			}else{
				var checked1 = 0;
				var checked2 = 0;
				for(var i=0;i<count;i++){
				var checked = childNodes[i].checked;
					if(checked==1){
						checked1++;
					}else if(checked==2){
						checked2++;
					}
				}
				this.checked = (childNodes.length==checked1) ? 1 : (checked1>0||checked2>0) ? 2 : 0;
			}
		}else{
			this.checked=checked;
		}
		this.paintCheckboxImg();
	},
	onCheck : function(){
		if(this.checked!==false){
			if(this.checked==1){
				this.cascade((function(checked){
					this.setCheck(checked);
				}),null,0);
				this.bubble((function(checked){
					this.setCheck(checked);
				}),null,2);
			}else{
				this.cascade((function(checked){
					this.setCheck(checked);
				}),null,1);
				this.bubble((function(checked){
					this.setCheck(checked);
				}),null,3);
			}
		}
	},
	/**
	 * 判断该结点是否根结点
	 */
	isRoot : function(){
		return (this.ownerTree!=null) && (this.ownerTree.root === this);
	},
	/**
	 * 判断该结点是否叶子结点
	 */
	isLeaf : function(){
		return this.leaf != false && this.childNodes.length===0;
		//return this.leaf === true;
  },
	isLast : function(){
		return (!this.parentNode ? true : this.parentNode.lastChild == this);
	},
	isFirst : function(){
		return (!this.parentNode ? true : this.parentNode.firstChild == this);
	},
	 
	hasChildNodes : function(){
		return !this.isLeaf() && this.childNodes.length > 0;
	},
	// private
	setFirstChild : function(node){
		this.firstChild = node;
	},
	//private
	setLastChild : function(node){
		this.lastChild = node;
	},
	/**
	 * 添加此结点的子结点
	 * @param node  待添加的子结点(TreeNode类型)
	 */
	appendChild : function(node){
		var multi = false;
		if(Array.isInstance(node)){
			multi = node;
		}else if(arguments.length > 1){
			multi = arguments;
		}
		if(multi){
    	for(var i = 0, len = multi.length; i < len; i++) {
				this.appendChild(multi[i]);
			}
		}else{
			//>>beforeappend
			//如果父节点不是复选节点，则子节点也不能是复选节点
			if(this.checked === false)
			{
				node.checked = false;
			}
			//如果父节点是未选中状态，则子节点是未选中状态
			else if(this.checked == 1)
			{
				node.checked = 1;
			}
			//如果父节点是半选中状态，则子节点是原始状态
			else if(this.checked == 2 && node.checked == false)
			{
				node.checked = 0;
			}
			//如果父节点未半选中状态，则子节点是未选中状态
			else if(this.checked == 0)
			{
				node.checked = 0;
			}
      var oldParent = node.parentNode;
      //>>beforemove
      if(oldParent){
				oldParent.removeChild(node);
			}
			var index = this.childNodes.length;
      if(index == 0){
				this.setFirstChild(node);
      }
			this.childNodes.push(node);
			node.parentNode = this;
			//
			var ps = this.childNodes[index-1];
			if(ps){
				node.previousSibling = ps;
				ps.nextSibling = node;
			}else{
				node.previousSibling = null;
			}
			node.nextSibling = null;
      this.setLastChild(node);
			node.setOwnerTree(this.getOwnerTree());
			//>>append
			//if(oldParent) >>move

			if(node && this.childrenRendered){
				node.render();
				if(node.previousSibling){
					node.previousSibling.paintPrefix();//paintLine();
				}
      }
      if(this['html-element']){
      	this.paintPrefix();
      }
			return node;//true
		}
	},
	/**
	 * 将此结点从树中删除，并同时将它的下级结点删除
	 */
	remove : function()
	{
		if(this.parentNode != null)
		{
			this.parentNode.removeChild(this);
		}
	}
	,
	/**
	 * 删除此结点的某个子结点
	 * @param node  待删除的子结点(TreeNode类型)
	 */
	removeChild : function(node){
	  var index = this.childNodes.indexOf(node);
	  if(index == -1){
	      return false;
	  }
		//>>beforeremove
		this.childNodes.splice(index, 1);
		if(node.previousSibling){
	  	node.previousSibling.nextSibling = node.nextSibling;
		}
		if(node.nextSibling){
	  	node.nextSibling.previousSibling = node.previousSibling;
		}
		if(this.firstChild == node){
	  	this.setFirstChild(node.nextSibling);
		}
		if(this.lastChild == node){
	  	this.setLastChild(node.previousSibling);
		}
		node.setOwnerTree(null);
		//clear
		node.parentNode = null;
		node.previousSibling = null;
		node.nextSibling = null;
		//>>remove UI
		if(this.childrenRendered){
			if(node['html-element']&&node['html-element']['element']){
				this['html-element']['child'].removeChild(node['html-element']['element'])	
			}
			if(this.childNodes.length==0){
				this.collapse();
			}
    }
    if(this['html-element']){
    	this.paintPrefix();
    }
		return node;
	},
	/**
	 * 当前结点做为父结点，将node添加到refNode之前
	 * @param node 待添加的结点
	 * @param refNode 将node添加到refNode之前
	 */
	insertBefore : function(node, refNode){
		if(!refNode){
			return this.appendChild(node);
		}
		//移动位置是自身位置(不需要移动)
		if(node == refNode){
			return false;
		}
		var index = this.childNodes.indexOf(refNode);
		var oldParent = node.parentNode;
		var refIndex = index;
		//是子节点，并且是向后移动
		if(oldParent == this && this.childNodes.indexOf(node) < index){
			refIndex--;
		}
		if(oldParent){
			oldParent.removeChild(node);
		}
		//设置节点间关系
		if(refIndex == 0){
			this.setFirstChild(node);
		}
		this.childNodes.splice(refIndex, 0, node);
		node.parentNode = this;
		var ps = this.childNodes[refIndex-1];
		if(ps){
			node.previousSibling = ps;
			ps.nextSibling = node;
		}else{
			node.previousSibling = null;
		}
		node.nextSibling = refNode;
		refNode.previousSibling = node;
		node.setOwnerTree(this.getOwnerTree());
		return node;
	},
	replaceChild : function(newChild, oldChild){
		this.insertBefore(newChild, oldChild);
		this.removeChild(oldChild);
		return oldChild;
	},
	indexOf : function(child){
		return this.childNodes.indexOf(child);
	},
	getOwnerTree : function(){
		if(!this.ownerTree){
			var p = this;
			while(p){
				if(p.ownerTree){
					this.ownerTree = p.ownerTree;
					break;
				}
				p = p.parentNode;
			}
		}
		return this.ownerTree;
	},
	//获得节点深度
	getDepth : function(){
  	var depth = 0;
		var p = this;
		while(p.parentNode){
			depth++;
			p = p.parentNode;
		}
		return depth;
	},
  //private
	setOwnerTree : function(tree){
		if(tree != this.ownerTree){
			if(this.ownerTree){
				this.ownerTree.unregisterNode(this);
			}
			this.ownerTree = tree;
			var cs = this.childNodes;
			for(var i = 0, len = cs.length; i < len; i++) {
				cs[i].setOwnerTree(tree);
			}
			if(tree){
				tree.registerNode(this);
			}
		}
	},
	getPathNodes : function(){
		var nodes = [];
		for(var parent=this; parent!=null; parent=parent.parentNode){nodes.push(parent);};
		return nodes.reverse();
	},
	getPath : function(attr){
		attr = attr || "id";
		var p = this.parentNode;
		var b = [this['attributes'][attr]];
		while(p){
			b.unshift(p.attributes[attr]);
			p = p.parentNode;
    }
		var sep = this.getOwnerTree().pathSeparator;
		return sep + b.join(sep);
	},
	//冒泡(遍历所有父节点)
	bubble : function(fn, scope, args){
  	var p = this;
		while(p){
			if(fn.call(scope || p, (args==null)?p:args) === false){
	    	break;
			}
	    p = p.parentNode;
		}
	},
	//瀑布(遍历所有子节点)
	cascade : function(fn, scope, args){
		if(fn.call(scope || this, (args==null)?this:args) !== false){
			var cs = this.childNodes;
			for(var i = 0, len = cs.length; i < len; i++) {
				cs[i].cascade(fn, scope, args);
			}
    }
	},
	//查找
	findChild : function(attribute, value){
		var cs = this.childNodes;
    for(var i = 0, len = cs.length; i < len; i++) {
			if(cs[i].attributes[attribute] == value){
      return cs[i];
     }
		}
		return null;
	},
  findChildBy : function(fn, scope){
      var cs = this.childNodes;
      for(var i = 0, len = cs.length; i < len; i++) {
      	if(fn.call(scope||cs[i], cs[i]) === true){
      	    return cs[i];
      	}
      }
      return null;
  },
  //该方法未完全实现
	sort : function(fn, scope){
		var cs = this.childNodes;
		var len = cs.length;
    if(len > 0){
			var sortFn = scope ? function(){fn.apply(scope, arguments);} : fn;
			cs.sort(sortFn);
			for(var i = 0; i < len; i++){
				var n = cs[i];
        n.previousSibling = cs[i-1];
        n.nextSibling = cs[i+1];
        if(i == 0){
        	this.setFirstChild(n);
         }
        if(i == len-1){
         	this.setLastChild(n);
				}
			}
		}
	},
  contains : function(node){
     var p = node.parentNode;
      while(p){
          if(p == this){
              return true;
          }
          p = p.parentNode;
      }
      return false;
  },
  toString : function(){
      return "[Node"+(this.id?" "+this.id:"")+"]";
  }
};
function HttpRequest()
{
	var m_httpObject = GetXMLHttpRequest();
	var m_callback = null;
	var m_basync = null;

	this.SendRequest = function(url,data,async,callback)
	{
		m_basync = async;
		m_callback = callback;
		m_httpObject.onreadystatechange = defaultResponseHandler;
		m_httpObject.open("POST", url, async);
		m_httpObject.setRequestHeader('cache-control','no-cache');  
		m_httpObject.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
		m_httpObject.send(data);
	}
	
	this.GetResponseText = function()
	{
		if(m_basync) return '';
		return m_httpObject.responseText;
	}
	
	this.GetResponseXml = function()
	{
		if(m_basync) return '';
		return m_httpObject.responseXML;
	}
	
	function defaultResponseHandler()
	{
		if(m_callback == null) return ;
		if(m_httpObject.readyState == 4 && m_httpObject.status == 200)
		{
			m_callback(m_httpObject.responseText,m_httpObject.responseXML);
		}
	}
	
	function GetXMLHttpRequest()
	{
		var xmlHttp = null;
		try
		{
			xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
		}
		catch( e )
		{
			try
			{
				xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
			}catch( e )
			{
				try
				{
					xmlHttp = new XMLHttpRequest();
				}catch( e )
				{
					return null;
				}
			}
		}
		return xmlHttp;
	}
}